home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / 92052tar.gz / 920528.tar / pathname.c < prev    next >
C/C++ Source or Header  |  1991-02-25  |  3KB  |  124 lines

  1. /* @(#) $Header: pathname.c,v 1.4 91/02/24 20:17:30 deyke Exp $ */
  2.  
  3. /* Convert relative to absolute pathnames
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6. #include <stdio.h>
  7. #include "global.h"
  8. #include "dirutil.h"
  9.  
  10. static void crunch __ARGS((char *buf,char *path));
  11.  
  12. /* Given a working directory and an arbitrary pathname, resolve them into
  13.  * an absolute pathname. Memory is allocated for the result, which
  14.  * the caller must free
  15.  */
  16. char *
  17. pathname(cd,path)
  18. char *cd;       /* Current working directory */
  19. char *path;     /* Pathname argument */
  20. {
  21.     register char *buf;
  22. #ifdef  MSDOS
  23.     char *cp,c;
  24.     char *tbuf;
  25.     int tflag = 0;
  26. #endif
  27.  
  28.     if(cd == NULLCHAR || path == NULLCHAR)
  29.         return NULLCHAR;
  30.  
  31. #ifdef  MSDOS
  32.     /* If path has any backslashes, make a local copy with them
  33.      * translated into forward slashes
  34.      */
  35.     if(strchr(path,'\\') != NULLCHAR){
  36.         tflag = 1;
  37.         cp = tbuf = mallocw(strlen(path));
  38.         while((c = *path++) != '\0'){
  39.             if(c == '\\')
  40.                 *cp++ = '/';
  41.             else
  42.                 *cp++ = c;
  43.         }
  44.         *cp = '\0';
  45.         path = tbuf;
  46.     }
  47. #endif
  48.  
  49.     /* Strip any leading white space on args */
  50.     while(*cd == ' ' || *cd == '\t')
  51.         cd++;
  52.     while(*path == ' ' || *path == '\t')
  53.         path++;
  54.  
  55.     /* Allocate and initialize output buffer; user must free */
  56.     buf = mallocw((unsigned)strlen(cd) + strlen(path) + 10);        /* fudge factor */
  57.     buf[0] = '\0';
  58.  
  59.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  60.     if(path[0] != '/')
  61.         crunch(buf,cd);
  62.  
  63.     crunch(buf,path);
  64.  
  65.     /* Special case: null final path means the root directory */
  66.     if(buf[0] == '\0'){
  67.         buf[0] = '/';
  68.         buf[1] = '\0';
  69.     }
  70. #ifdef  MSDOS
  71.     if(tflag)
  72.         free(tbuf);
  73. #endif
  74.     return buf;
  75. }
  76.  
  77. /* Process a path name string, starting with and adding to
  78.  * the existing buffer
  79.  */
  80. static void
  81. crunch(buf,path)
  82. char *buf;
  83. register char *path;
  84. {
  85.     register char *cp;
  86.  
  87.     cp = buf + strlen(buf); /* Start write at end of current buffer */
  88.  
  89.     /* Now start crunching the pathname argument */
  90.     for(;;){
  91.         /* Strip leading /'s; one will be written later */
  92.         while(*path == '/')
  93.             path++;
  94.         if(*path == '\0')
  95.             break;          /* no more, all done */
  96.         /* Look for parent directory references, either at the end
  97.          * of the path or imbedded in it
  98.          */
  99.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  100.             /* Hop up a level */
  101.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  102.                 cp = buf;       /* Don't back up beyond root */
  103.             *cp = '\0';             /* In case there's another .. */
  104.             path += 2;              /* Skip ".." */
  105.             while(*path == '/')     /* Skip one or more slashes */
  106.                 path++;
  107.         /* Look for current directory references, either at the end
  108.          * of the path or imbedded in it
  109.          */
  110.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  111.             /* "no op" */
  112.             path++;                 /* Skip "." */
  113.             while(*path == '/')     /* Skip one or more slashes */
  114.                 path++;
  115.         } else {
  116.             /* Ordinary name, copy up to next '/' or end of path */
  117.             *cp++ = '/';
  118.             while(*path != '/' && *path != '\0')
  119.                 *cp++ = *path++;
  120.         }
  121.     }
  122.     *cp++ = '\0';
  123. }
  124.